package com.prateekj.snooper.espresso;
import android.support.annotation.NonNull;
import android.support.test.espresso.PerformException;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.util.HumanReadables;
import android.view.View;
import org.hamcrest.CustomTypeSafeMatcher;
import org.hamcrest.Matcher;
import static android.support.test.espresso.Espresso.registerIdlingResources;
import static android.support.test.espresso.Espresso.unregisterIdlingResources;
import static java.lang.String.format;
public class WaitForViewAction implements ViewAction {
private Matcher<View> viewMatcher;
private int timeout;
public WaitForViewAction(Matcher<View> viewMatcher, int timeout) {
this.viewMatcher = viewMatcher;
this.timeout = timeout;
}
@Override
public Matcher<View> getConstraints() {
return anyView();
}
@Override
public String getDescription() {
return format("performing wait for until view matcher %s matches", viewMatcher.toString());
}
@Override
public void perform(UiController uiController, View view) {
ViewMatcherIdlingResource idlingResource = new ViewMatcherIdlingResource(timeout, viewMatcher, view);
registerIdlingResources(idlingResource);
uiController.loopMainThreadUntilIdle();
unregisterIdlingResources(idlingResource);
if(!idlingResource.isMatched()) {
throw new PerformException.Builder()
.withActionDescription(getDescription())
.withViewDescription(HumanReadables.getViewHierarchyErrorMessage(view, null, "Action timed out : " + getDescription(), null))
.build();
}
}
@NonNull
private CustomTypeSafeMatcher<View> anyView() {
return new CustomTypeSafeMatcher<View>("") {
@Override
protected boolean matchesSafely(View item) {
return true;
}
};
}
}